#include "process.h"

using namespace std;

//Default constructor
Process::Process() {
	pid = 0;
	burst = 0;
	time_remaining = 0;
	arrival = 0;
	priority = 0;
	orig_priority = 0;
	deadline = 0;
	io = 0;
	wait_start = -1;
}

//Constructor
Process::Process(int id, int bu, int arr, int pr, int dl, int i_o) {
	pid = id;
	burst = bu;
	time_remaining = bu;
	arrival = arr;
	priority = pr;
	orig_priority = pr;
	deadline = dl;
	io = i_o;
	wait_start = -1;
}

Process::~Process() {

}

void Process::clone(Process p) {
   pid = p.get_pid();
   burst = p.get_burst();
	time_remaining = p.get_t_remain();
	arrival = p.get_arrival(); 
	priority = p.get_priority(); 
	orig_priority = p.get_orig_pri(); 
	deadline = p.get_deadline(); 
	io = p.get_io();
	wait_start = p.get_wait_start();
}

void Process::run_for(int time) {
	time_remaining = time_remaining - time;
	if(time_remaining < 0) {
		time_remaining = 0;
	}
}

bool Process::has_arrived(int clk) {
	return (arrival <= clk);
}

bool Process::is_done() {
	return (time_remaining == 0);
}

void Process::wait_at(int clk) {
	wait_start = clk;
}

bool Process::age_up(int clk, int aging_time) {
	return ((wait_start >= clk) && (clk - wait_start) >= aging_time);
}

bool Process::operator==(Process p) {
	bool result = true;
	
	if(pid == p.get_pid()) {
		if(burst == p.get_burst()) {
			if(time_remaining == p.get_t_remain()) {
				if(arrival == p.get_arrival()) {
					if(priority == p.get_priority()) {
						if(orig_priority == p.get_orig_pri()) {
							if(deadline == p.get_deadline()) {
								if(io == p.get_io()) {
									if(wait_start == p.get_wait_start()) {
										result = true;
									} else {
										result = false;
									}
								} else {
									result = false;
								}
							} else {
								result = false;
							}
						} else {
							result = false;
						}
					} else {
						result = false;
					}
				} else {
					result = false;
				}
			} else {
				result = false;
			}
		} else {
			result = false;
		}
	} else {
		result = false;
	}
	
	return result;
}

//Update the priority of a process
void Process::update_priority(int new_priority) {
	priority = new_priority;
}

//Get the string representation of a process
string Process::to_string() {
	stringstream stream;
	stream << "'" << pid << "'";

	return stream.str();
}

int Process::get_pid(){
	return pid;
}

int Process::get_burst() {
	return burst;
}

int Process::get_t_remain() {
	return time_remaining;
}

int Process::get_arrival() {
	return arrival;
}

int Process::get_priority() {
	return priority;
}

int Process::get_orig_pri() {
	return orig_priority;
}

int Process::get_deadline() {
	return deadline;
}

int Process::get_wait_start() {
	return wait_start;
}

int Process::get_io() {
	return io;
}
